#pragma once
#include <xpam/serialization/serialize.h>
#include <xpam/serialization/naming.h>
#include <xpam/exception.h>
#include <xpam/lexical_cast.h>
#include <vector>
namespace xpam
{
    namespace serialization
    {
        class istorage_txt
        {
            std::istream & stream;
            std::vector<std::string> names;
            std::string generate_name()
            {
                std::string s;
                for (int i = 0; i < (int)names.size(); i++)
                    s += "." + names[i];
                return s;
            }
        public:
            istorage_txt(std::istream & s) : stream(s)
            { }

            void push_name(const std::string & n)
            {
                names.push_back(n);
            }

            void pop_name()
            {
                names.resize(names.size() - 1);
            }

            template<class T>
            void read(T & t)
            {
                std::string line;
                std::getline(stream, line);
                std::string gen = generate_name();
                int pos = line.find("=");
                if (pos == std::string::npos)
                    throw xpam::exception() << "syntax error in line:" << line;
                std::string sub = line.substr(0, pos);
                if (sub != gen)
                    throw xpam::exception() << "expect " << gen << " in line:" << line;
                t = lexical_cast<T>(line.substr(pos + 1));
            }
        };
        
        //template<typename T>
        //void serialize(istorage_txt & s, T & t)
        //{
        //    s.read(t);
        //}

        inline void serialize(istorage_txt & s, int & t)
        {
            s.read(t);
        }
        
        inline void serialize(istorage_txt & s, bool & t)
        {
            s.read(t);
        }

        inline void serialize(istorage_txt & s, std::string & t)
        {
            s.read(t);
        }

        template<class T>
        void serialize(istorage_txt & s, std::vector<T> & t)
        {
            int n;
            serialize(s, naming(n, "count"));
            t.resize(n);
            for (int i = 0; i < n; i++)
                serialize(s, naming(t[i], "item[" + lexical_cast<std::string>(i) + "]"));
        }
    }
}